/*
 *  Sound.h
 *  SoundController0002
 *
 *  Created by jiro on 11/06/16.
 *  Copyright 2011 jiro music. All rights reserved.
 *
 */

#pragma once 

#include "../../sc/Common/Note.h"
#include "../../sc/SoundElement.h"
#include <vector>
#include <map>

namespace sc
{
namespace hs
{

	class HarmonicSound;

	class Sound
	{
	public:

		//	key:	base note number and harmonic multiple nearby key, as type HarmonicSound
		//	value:	nearby note on 12 note well temperament
		//	remark: these notes are not included octave notes itself
		typedef std::multimap< HarmonicSound, sc::Note::MidiNumber > NearbyWellTemperamentNotes;

		typedef std::pair< HarmonicSound, sc::Note::MidiNumber > NearbyWellTemperamentNotePair;

		enum WaveType
		{
			SawWave,		///	amplitude 1 / n, include all harmonics

			SquareWave,		///	amplitude 1 / n, include odd harmonics

			TriangleWave,	///	amplitude 1 / n^2, include odd harmonics
			
			SingleSineWave,	///	amplitude 1, include only 1st harmonics

			Unknown,

		};

	private:

		WaveType type;

		::sc::Note::MidiNumber midiNumber;

		double dynamics;

		double frequency;

		NearbyWellTemperamentNotes nearbyWellTemeramentNotes;

	public:

		Sound();

		Sound( WaveType type, ::sc::Note::MidiNumber midiNumber );

		Sound( WaveType type, ::sc::Note::MidiNumber midiNumber, double dynamics );

		Sound( double frequency );

		Sound( double frequency, double dynamics );

		WaveType GetWaveType() const;

		sc::Note::MidiNumber GetMidiNumber() const;

		virtual double GetFrequency() const;

		double GetDynamics() const;

		int GetHarmonicsCount() const;

		double GetHarmonics( int nth ) const;

		double GetHarmonicAmplitude( int nth ) const;

		double GetHarmonicWeight( int nth ) const;

		bool ContainHarmonics( double harmonicsFrequency ) const;

		void GetAllHarmonics( std::vector< double >& harmonics ) const;

		const NearbyWellTemperamentNotes& GetNearbyWellTemperamentNotes();

		//	for stl map / set
		bool operator != ( const Sound& rhs ) const;

		//	for stl map / set
		bool operator < ( const Sound& rhs ) const;

		bool operator == ( const Sound& rhs ) const;

		std::string ToString( int tabCount = 0) const;

		static std::string ToString( WaveType type );

		static std::string ToString( const NearbyWellTemperamentNotes& notes, int harmonicNthMax, bool isCSV, bool displayOctave, bool verBose );

		static std::string ToString( const std::vector< NearbyWellTemperamentNotes >& notesList, int harmonicNthMax, bool isCSV, bool displayOctave, bool verBose );

	private:
	
	};

}
}
